using System;
using System.Collections;
using System.Text;

namespace G2007.CodeGen.Library.Data
{
    public class Helper
    {
        public static bool hasParam ( string[] dataBlocks , string val )
        {
            for ( int z = 2 ; z < dataBlocks.Length ; z++ )
            {
                if ( dataBlocks[ z ].Trim ().ToUpper ().Equals ( val.ToUpper () ) ) return true;
            }
            return false;
        }


		public static string hasParamValue ( string[] dataBlocks, string typeName )
		{
			for ( int z = 2 ; z < dataBlocks.Length ; z++ )
			{
				if ( dataBlocks[ z ].Trim ().Split ( ':' )[ 0 ].ToUpper ().Equals ( typeName.ToUpper () ) )
				{
					return dataBlocks[ z ].Split (':').Length == 2?dataBlocks[ z ].Trim ().Split ( ':' )[ 1 ].Trim():string.Empty;
				}
			}

			return string.Empty;
		}


        public static ClassAttributes[] ExtractAttributes ( out string error , CGObject ito)
        {
			ClassAttributes[] classAttributes;
			genericAttributes ( ito , (ito is Class)?"CLASS":"INSTANCE" , out error , out classAttributes );
            return classAttributes;
        }


        
		private static void genericAttributes ( CGObject @class , string type , out string error , out ClassAttributes[] classAttributes )
		{

			error = "";
			classAttributes = null;

			// need to find the class in the data and then generate it
			int x = 0;

			foreach ( string s in @class.Data )
			{
				if ( s.ToUpper ().StartsWith ( type ) )
				{
					if ( s.Split ( '\t' ).Length > 1 )
					{
						if ( s.Split ( '\t' )[ 1 ].Trim ().Equals ( @class.Name ) )
						{
							// we have found the matcing data - now we need to 
							// read until we get to end class x hold the
							// current line, so we just need to read from data
							//  from there onwards
							ArrayList vals = new ArrayList ();
							int y = x + 1;
							while ( y < @class.Data.Length )
							{
								if ( @class.Data[ y ].ToUpper ().Trim ().Equals ( "END " + type ) )
									break;

								if ( @class.Data[ y ].Split ( '\t' ).Length > 1 )
								{

									string[] dataBlocks = @class.Data[ y ].Split ( '\t' );
									string attributeName = dataBlocks[ 0 ].Trim ();
									string attributeType = dataBlocks[ 1 ].Trim ().Replace ( "[]" , "" );
									ClassType classType = dataBlocks[ 1 ].Trim ().EndsWith ( "[]" ) ? ClassType.array : ClassType.single;

									bool toString = hasParam ( dataBlocks , "TOSTRING" );
									bool hidden = hasParam ( dataBlocks , "HIDDEN" );
									bool compare = hasParam ( dataBlocks , "COMPARE" );
									bool key = hasParam ( dataBlocks, "KEY" );
									bool identity = hasParam ( dataBlocks, "IDENTITY" );
									bool hasMany = hasParam ( dataBlocks, "HASMANY" );
									bool isNested = hasParam ( dataBlocks, "NESTED" );

									string tableName = hasParamValue ( dataBlocks, "TABLENAME" );
									string columnRef = hasParamValue ( dataBlocks, "COLREF" );
									string columnKey = hasParamValue ( dataBlocks, "COLKEY" );
									string where = hasParamValue ( dataBlocks, "WHERE" );
									string dbName = hasParamValue ( dataBlocks, "DBNAME" ).Equals ( string.Empty ) ? attributeName.Replace ( DBConvertor.DBToScript.FIELD_CLASS_NAME_MATCH_EXTENDER,"" ):
										hasParamValue ( dataBlocks, "DBNAME" );

									vals.Add ( new ClassAttributes ( attributeName , attributeType , classType , @class.OtherClasses ,
										@class.Enums , toString , hidden , @class.Name , compare , 
										key , identity, dbName, tableName, columnRef, columnKey, where, hasMany, isNested ) );
								}

								y++;
							}

							classAttributes =
								( ClassAttributes[] ) vals.ToArray ( typeof ( ClassAttributes ) );
						}
					}
				}
				x++;
			}
		}
    }
}
